#ifndef TEST_TINYXML_H
#define TEST_TINYXML_H

#include "../src/persistencia/tinyxml/tinyxml.h"
#include "../src/common/Constantes.h"
#include <stdio.h>
#include <string>

#include <iostream>
using namespace std;

class Test_TinyXML{
private:
	cadena pathArchivoXml;
public:
	Test_TinyXML(cadena pathArchivoXml);

	//ESCRIBE el xml con el mismo formato que tiene 'pathArchivoXml'
	void escribirXML();

	//LEE el xml y lo imprime por pantalla con el mismo formato que tiene 'pathArchivoXml'
	void leerXML();

private:
	//crea y escribe un escenario con el nombre y el fondo pasado por parametros.
	//Este escenario sera colgado de nodoEscenarios pasado por parametro.
	//return: nodo del escenario creado.
	TiXmlNode* crearEscenario(TiXmlNode* nodoEscenarios, cadena nombre, cadena fondo);

	//crea y escribe un objeto con el nombre y la posx y posY pasado por parametro
	//Este objeto sera colgado de nodoEscenario pasado por parametro.
	void crearObjeto(TiXmlNode* nodoEscenario,cadena nombre,numero posX,numero posY);

	//crea los objetos habilitados
	void crearObjetoHabilitado(TiXmlNode* nodoObjetosHabilitados,cadena nombre, numero posX, numero posY,cadena accion, cadena path);

	//imprime los atributos del el tag pasado por parametro
	void imprimirAtributosDe(TiXmlElement* unTag);

	//imprime el hijo de la raiz pasado por parametro, dejando el 'tab' correspondiente
	//para poder simular el formato de el archivo xml
	void imprimirHijo(TiXmlElement* unHijo);

	//imprime el nieto de la raiz pasado por parametro, dejando el 'tab' correspondiente
	void imprimirNieto(TiXmlElement* unNieto);

	//imprime el bis-nieto de la raiz pasado por parametro, dejando el 'tab' correspondiente
	void imprimirBisNietos(TiXmlElement* unBisNieto);
};
#endif

//implementaciones
	Test_TinyXML::Test_TinyXML(cadena pathArchivoXml){
		this->pathArchivoXml = pathArchivoXml;
	}

	void Test_TinyXML::escribirXML(){
		//creo una archivo xml nuevo
		TiXmlDocument doc("");
		cadena nombreNuevoXML = "./src/persistencia/archivosXML/nuevoXML.xml";
		if  (doc.SaveFile(nombreNuevoXML.c_str())){
			cout<<"inicia la ESCRITURA del xml en el directorio: "<<nombreNuevoXML<<endl;

			//creo el tag DISEÑO_ESCENARIO
			TiXmlElement * tagDisenioEscenario = new TiXmlElement("DISEÑO_ESCENARIO");
			TiXmlNode* nodoDisenioEscenario = doc.LinkEndChild(tagDisenioEscenario);

			//creo el tag ESCENARIOS
			TiXmlElement * tagEscenarios = new TiXmlElement("ESCENARIOS");
			TiXmlNode* nodoEscenarios = nodoDisenioEscenario->LinkEndChild(tagEscenarios);

			//creo PRIMER ESCENARIO
			TiXmlNode* nodoEscenario1 = this->crearEscenario(nodoEscenarios,"desierto","./fondos/desierto.bmp");
			this->crearObjeto(nodoEscenario1,"arma-letal",10,10);
            this->crearObjeto(nodoEscenario1,"arbol",30,10);
            this->crearObjeto(nodoEscenario1,"cabaña",40,10);
            this->crearObjeto(nodoEscenario1,"cañon",43,10);
            this->crearObjeto(nodoEscenario1,"arbol",35,10);
            this->crearObjeto(nodoEscenario1,"arma-letal",50,10);

            //creo SEGUNDO ESCENARIO
			TiXmlNode* nodoEscenario2 = this->crearEscenario(nodoEscenarios,"Montaña","./fondos/montaña.bmp");
			this->crearObjeto(nodoEscenario2,"arma-letal",100,10);
            this->crearObjeto(nodoEscenario2,"arma-letal",50,10);

            //creo TERCER ESCENARIO
			TiXmlNode* nodoEscenario3 = this->crearEscenario(nodoEscenarios,"Selva","./fondos/selva.bmp");

			//creo CUARTO ESCENARIO
			TiXmlNode* nodoEscenario4 = this->crearEscenario(nodoEscenarios,"Llanura","./fondos/llanura.bmp");

			//creo el tag OBJETOS
			TiXmlElement * tagObjetosHabilitados = new TiXmlElement("OBJETOS");
			TiXmlNode* nodoObjetosHabilitados = nodoDisenioEscenario->LinkEndChild(tagObjetosHabilitados);

			//creo los objetos habilitados
			this->crearObjetoHabilitado(nodoObjetosHabilitados,"arma-letal",0,0,"explotar","./objetos/tanque-1.bmp");
	        this->crearObjetoHabilitado(nodoObjetosHabilitados,"arbol",0,0,"detenerTanque","./objetos/arbol.bmp");
	        this->crearObjetoHabilitado(nodoObjetosHabilitados,"cabaña",0,0,"cargarMunisiones","./objetos/cabaña.bmp");
	        this->crearObjetoHabilitado(nodoObjetosHabilitados,"cañon",0,0,"destruirTanque","./objetos/cañon.bmp");

			//para escribir un texto entre el tag de inicio y de cierre
			//TiXmlText * comentarioPrincipal = new TiXmlText( "contenido" );
			//tagPadre->LinkEndChild(comentarioPrincipal);

			//aplico los cambios, guardando el archivo
			doc.SaveFile(nombreNuevoXML.c_str());
			cout<<"termina la ESCRITURA del xml"<<endl;
		}
		else{
			cout<<"main.cpp - NO se pudo escribir el archivo XML"<<endl;
		}
	}

	void Test_TinyXML::leerXML(){
		cout<<"inicia la LECTURA del xml"<<endl;
		TiXmlDocument doc(this->pathArchivoXml.c_str());
		if (doc.LoadFile()) {
			// <animales>
			TiXmlElement *root = doc.RootElement();
			const char* nombreTagPadre = root->Value();
			cout<<"<"<<nombreTagPadre<<">"<<endl;
			// recorreo todos los hijos de la raiz (diseños escenarios)
			TiXmlElement* hijo; //para recorrer los escenarios, obejtos y fondos
			for(hijo = root->FirstChildElement(); hijo; hijo = hijo->NextSiblingElement()) {
				imprimirHijo(hijo);
				//recorro todos los nietos de la raiz
				TiXmlElement* nieto;
				for(nieto = hijo->FirstChildElement(); nieto; nieto = nieto->NextSiblingElement()) {
					imprimirNieto(nieto);
					//recorro todos los bis-nietos de la raiz
					TiXmlElement* bisNieto;
					for(bisNieto = nieto->FirstChildElement(); bisNieto; bisNieto = bisNieto->NextSiblingElement()){
						imprimirBisNietos(bisNieto);
					}
					//cierro el tag del nieto de la raiz
					cout<<"\t\t</"<<nieto->Value()<<">"<<endl;
				}
				//cierro el tag del hijo de la raiz
				cout<<"\t</"<<hijo->Value()<<">"<<endl;
			}
			//cierro el tag raiz
			cout<<"</"<<nombreTagPadre<<">"<<endl;
		}
		else{
			cout<<"test_tinyxml.h - no se pudo leer el archivo xml"<<endl;
		}
	}

	TiXmlNode* Test_TinyXML::crearEscenario(TiXmlNode* nodoEscenarios, cadena nombre, cadena fondo){
		TiXmlElement * tagEscenario = new TiXmlElement("ESCENARIO");
		TiXmlNode* nodoEscenario = nodoEscenarios->LinkEndChild(tagEscenario);
		TiXmlElement* escenario = nodoEscenario->ToElement();
		escenario->SetAttribute("nombre",nombre.c_str());
		escenario->SetAttribute("fondo",fondo.c_str());
		return nodoEscenario;
	}

	void Test_TinyXML::crearObjeto(TiXmlNode* nodoEscenario,cadena nombre,numero posX,numero posY){
		TiXmlElement * tagObjeto = new TiXmlElement("OBJETO");
		TiXmlElement* objeto = nodoEscenario->LinkEndChild(tagObjeto)->ToElement();
		objeto->SetAttribute("nombre",nombre.c_str());
		objeto->SetAttribute("posX",posX);
		objeto->SetAttribute("posY",posY);
	}

	void Test_TinyXML::crearObjetoHabilitado(TiXmlNode* nodoObjetosHabilitados,cadena nombre, numero posX, numero posY,cadena accion, cadena path){
		TiXmlElement * tagObjetoHabilitado = new TiXmlElement("OBJETO");
		TiXmlElement* objetoHabilitado = nodoObjetosHabilitados->LinkEndChild(tagObjetoHabilitado)->ToElement();
		objetoHabilitado->SetAttribute("nombre",nombre.c_str());
		objetoHabilitado->SetAttribute("posX",posX);
		objetoHabilitado->SetAttribute("posY",posY);
		objetoHabilitado->SetAttribute("accion",accion.c_str());
		objetoHabilitado->SetAttribute("path",path.c_str());
	}

	void Test_TinyXML::imprimirAtributosDe(TiXmlElement* unTag){
		const TiXmlAttribute* atributo;
		for (atributo = unTag->FirstAttribute(); atributo ; atributo = atributo->Next())
			cout<<atributo->Name()<<" = "<<unTag->Attribute(atributo->Name())<<" ";
	}

	void Test_TinyXML::imprimirHijo(TiXmlElement* unHijo){
		cout<<"\t<"<<unHijo->Value()<<" ";
		imprimirAtributosDe(unHijo);
		cout<<">"<<endl;
	}

	void Test_TinyXML::imprimirNieto(TiXmlElement* unNieto){
		cout<<"\t\t<"<<unNieto->Value()<<" ";
		imprimirAtributosDe(unNieto);
		cout<<">"<<endl;
	}

	void Test_TinyXML::imprimirBisNietos(TiXmlElement* unBisNieto){
		cout<<"\t\t\t<"<<unBisNieto->Value()<<" ";
		imprimirAtributosDe(unBisNieto);
		cout<<"/>"<<endl;
	}
